package com.xxl.job.admin.controller.resolver;

import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.util.JacksonUtil;

import lombok.extern.slf4j.Slf4j;

import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * Spring MVC 全局异常处理
 * @author xuxueli 2016-1-6 19:22:18
 */
@Slf4j
public class WebExceptionResolver implements HandlerExceptionResolver {

	@Override
	public ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex) {
		
		if(handler instanceof ResourceHttpRequestHandler) {
			//避免打印错误的log
			return null;
		}
		
		String servletPath = request.getServletPath();
		String className = null;
		if(handler != null) {
			className = handler.getClass().getName();
		}
		StringBuilder stringBuilder = new StringBuilder();
    	StackTraceElement[] elements = ex.getStackTrace();
		int length = elements.length;
		for(int i=0;i<length;i++) {
			stringBuilder.append("\n"+elements[i].toString());
		}
		
		log.error("捕获全局异常handlerName : [{}], servletPath : [{}], exception : [{}], StackTraceElement : {}",
				className,servletPath,ex,stringBuilder.toString());

		// if json
		boolean isJson = false;
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		ResponseBody responseBody = handlerMethod.getMethodAnnotation(ResponseBody.class);
		if (responseBody != null) {
			isJson = true;
		}
		

		// error result
		ReturnT<String> errorResult = new ReturnT<String>(ReturnT.FAIL_CODE, ex.toString().replaceAll("\n", "<br/>"));

		// response
		ModelAndView mv = new ModelAndView();
		if (isJson) {
			try {
				response.setContentType("application/json;charset=utf-8");
				response.getWriter().print(JacksonUtil.writeValueAsString(errorResult));
			} 
			catch (IOException e) {
				log.error(e.getMessage(), e);
			}
			return mv;
		}
		else {
			mv.addObject("exceptionMsg", errorResult.getMsg());
			mv.setViewName("/common/common.exception");
			return mv;
		}
	}
}